package cloud.seri.iot.manager.web.rest

import cloud.seri.iot.manager.service.DeviceService
import cloud.seri.iot.manager.service.dto.DeviceDTO
import cloud.seri.iot.manager.service.dto.DeviceStatisticsDTO
import cloud.seri.iot.manager.web.rest.errors.BadRequestAlertException
import io.github.jhipster.web.util.HeaderUtil
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import net.dreamlu.mica.core.result.R
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Value
import org.springframework.data.mongodb.datatables.DataTablesInput
import org.springframework.data.mongodb.datatables.DataTablesOutput
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.net.URISyntaxException
import javax.validation.Valid

/**
 * REST controller for managing [cloud.seri.iot.manager.domain.Device].
 */
@RestController
@RequestMapping("/api")
class DeviceResource(
    val deviceService: DeviceService
)
{

    private val log = LoggerFactory.getLogger(this.javaClass)

    @Value("\${jhipster.clientApp.name}")
    private var applicationName: String? = null

    /**
     * `POST  /devices` : Create a new device.
     *
     * @param deviceDTO the deviceDTO to create.
     * @return the [ResponseEntity] with status `201 (Created)` and with body the new deviceDTO, or with status `400 (Bad Request)` if the device has already an ID.
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @PostMapping("/devices")
    @ApiOperation("创建设备", nickname = "CreateDevice")
    fun createDevice(@Valid @RequestBody deviceDTO: DeviceDTO): R<DeviceDTO>
    {
        log.debug("REST request to save Device : {}", deviceDTO)
        if (deviceDTO.iotId != null)
        {
            throw BadRequestAlertException("A new device cannot already have an ID", ENTITY_NAME, "idexists")
        }
        return deviceService.createDevice(deviceDTO)
    }

    /**
     * `PUT  /devices` : Updates an existing device.
     *
     * @param deviceDTO the deviceDTO to update.
     * @return the [ResponseEntity] with status `200 (OK)` and with body the updated deviceDTO,
     * or with status `400 (Bad Request)` if the deviceDTO is not valid,
     * or with status `500 (Internal Server Error)` if the deviceDTO couldn't be updated.
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @PutMapping("/devices")
    @ApiOperation("更新设备", nickname = "UpdateDevice")
    fun updateDevice(@Valid @RequestBody deviceDTO: DeviceDTO): ResponseEntity<DeviceDTO>
    {
        log.debug("REST request to update Device : {}", deviceDTO)
        if (deviceDTO.productKey == null)
        {
            throw BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull")
        }
        val result = deviceService.save(deviceDTO)
        return ResponseEntity.ok()
            .headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, deviceDTO.productKey.toString()))
            .body(result)
    }

    /**
     * `GET  /devices` : get all the devices.
     *
     * @return the [ResponseEntity] with status `200 (OK)` and the list of devices in body.
     */
    @GetMapping("/devices")
    @ApiOperation("查询全部设备", nickname = "QueryAllDevices", hidden = true)
    fun queryAllDevices(): MutableList<DeviceDTO>
    {
        log.debug("REST request to get all Devices")
        return deviceService.findAll()
    }

    @PostMapping("/data/devices")
    @ApiOperation("查询设备列表", nickname = "QueryDevices")
    fun queryDevices(@RequestParam  pk: String?, @RequestBody input: DataTablesInput): DataTablesOutput<DeviceDTO>
    {
        return deviceService.getDevices(pk, input)
    }

    /**
     * `GET  /devices/:id` : get the "id" device.
     *
     * @param id the id of the deviceDTO to retrieve.
     * @return the [ResponseEntity] with status `200 (OK)` and with body the deviceDTO, or with status `404 (Not Found)`.
     */
    @GetMapping("/devices/{id}")
    @ApiOperation("查询设备详情", nickname = "QueryDeviceDetail")
    fun queryDeviceDetail(@PathVariable id: String): R<DeviceDTO>
    {
        log.debug("REST request to get Device : {}", id)
        return deviceService.findOne(id)
    }

    /**
     * `DELETE  /devices/:id` : delete the "id" device.
     *
     * @param id the id of the deviceDTO to delete.
     * @return the [ResponseEntity] with status `204 (NO_CONTENT)`.
     */
    @DeleteMapping("/devices/{id}")
    @ApiOperation("删除设备", nickname = "DeleteDevice")
    fun deleteDevice(@PathVariable id: String): R<Void>?
    {
        log.debug("REST request to delete Device : {}", id)

        return deviceService.delete(id)
    }

    @GetMapping("statistics")
    @ApiOperation("查询设备统计数据", nickname = "QueryDeviceStatistics")
    fun queryDeviceStatistics(@RequestParam(required = false) pk: String?): R<DeviceStatisticsDTO>?
    {
        log.debug("查询设备统计数据 : {}", pk)
        return deviceService.queryDeviceStatistics(pk)
    }

    companion object
    {
        private const val ENTITY_NAME = "seriIotManagerDevice"
    }
}
